/**
 * 
 */
package com.platform.common.utils;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * <pre>
 * 功能：Bean操作工具类
 * </pre>
 * 
 * @author wei.gao
 */
public class BeanUtils extends org.apache.commons.beanutils.BeanUtils {
	
	/**
	 * <pre>
	 * 功能：得到属性的描述
	 * </pre>
	 * 
	 * @param obj
	 * @param propertyName
	 * @return
	 * @throws IntrospectionException
	 */
	public static PropertyDescriptor getPropertyDescriptor(Object obj, String propertyName) throws IntrospectionException {
		BeanInfo bi = Introspector.getBeanInfo(obj.getClass());
		PropertyDescriptor[] pds = bi.getPropertyDescriptors();
		for (PropertyDescriptor propertyDescriptor : pds) {
			if ("propertyName".equals(propertyDescriptor.getName())) {
				return propertyDescriptor;
			}
		}
		return null;
	}
	
	/**
	 * <pre>
	 * 功能：给当前对象set属性值
	 * </pre>
	 * 
	 * @param obj
	 * @param pd
	 * @param value
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public static void setProperty(Object obj, PropertyDescriptor pd, Object value) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		// 从属性描述器中获取 set 方法
		Method setMethod = pd.getWriteMethod();
		// 调用set方法将传入的value值保存属性中去
		setMethod.invoke(obj, new Object[] { value });
	}
	
	/**
	 * <pre>
	 * 功能：调用属性的get方法
	 * </pre>
	 * 
	 * @param obj
	 * @param pd
	 * @return
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public static Object getProperty(Object obj, PropertyDescriptor pd) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Method getMethod = pd.getReadMethod();// 从属性描述器中获取 get 方法
		Object value = getMethod.invoke(obj);// 调用方法获取方法的返回值
		return value;// 返回值
	}
	
	/**
	 * <pre>
	 * 功能：利用org.apache.commons.beanutils 工具类实现map to bean
	 * </pre>
	 * 
	 * @param map
	 * @param obj
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 */
	public static void map2Bean2(Map<String, Object> map, Object obj) throws IllegalAccessException, InvocationTargetException {
		if (map == null || obj == null) {
			return;
		}
		populate(obj, map);
	}
	
	/**
	 * <pre>
	 * 功能：将map转为javabean
	 * </pre>
	 * 
	 * @param map
	 * @param obj
	 * @throws IntrospectionException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public static void map2Bean(Map<String, Object> map, Object obj) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		
		for (PropertyDescriptor property : propertyDescriptors) {
			String key = property.getName();
			
			if (map.containsKey(key)) {
				Object value = map.get(key);
				// 得到property对应的setter方法
				Method setter = property.getWriteMethod();
				setter.invoke(obj, value);
			}
			
		}
		return;
	}
	
	/**
	 * <pre>
	 * 功能：java对象向转为map
	 * </pre>
	 * 
	 * @param obj
	 * @return
	 * @throws IntrospectionException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public static Map<String, Object> bean2Map(Object obj) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		if (obj == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (PropertyDescriptor property : propertyDescriptors) {
			String key = property.getName();
			
			// 过滤class属性
			if (!key.equals("class")) {
				// 得到property对应的getter方法
				Method getter = property.getReadMethod();
				Object value = getter.invoke(obj);
				
				map.put(key, value);
			}
			
		}
		return map;
	}
	
}
